package com.sk.skplanet.commute.views;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.ActionBar;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.sk.skplanet.commute.R;
import com.sk.skplanet.commute.actions.APIRequestBus2;
import com.sk.skplanet.commute.actions.APIRequestBus2.OnBusRequestCompleted;
import com.sk.skplanet.commute.actions.APIRequestBus2.RequestMethod;
import com.sk.skplanet.commute.actions.Actions;
import com.sk.skplanet.commute.controllers.DialogController;
import com.sk.skplanet.commute.controllers.DialogController.OnDeleteCompleted;
import com.sk.skplanet.commute.daofactory.LocalDaoFactory;
import com.sk.skplanet.commute.vo.GetStationByUidVo;
import com.sk.skplanet.commute.vo.Point;
import com.sk.skplanet.commute.vo.StopInfo;

public class PointList extends ListActivity implements OnBusRequestCompleted, OnDeleteCompleted {
	// Variables
	private final int SEARCH_BUS_ACTIVITY = 1;
	private final int TIMER_INTERVAL = 20000;
	private int pointId;
	private Point point;
	private List<StopInfo> stopInfos;
	private PointListViewAdapter adapter;
	private int position;
	private ActionBar actionBar;
	private MenuItem refreshingIcon;
	private Timer timer;
	private TimerTask timerTask;
	private ProgressBar progressBar;
	
	// Private Methods
	private void sortBusStopInfo() {
		Collections.sort(stopInfos, mComparator);
		adapter.notifyDataSetChanged();
	}
	private void refreshBusStopInfo() {
		if(stopInfos.size() < 1) {
			progressBar.setVisibility(View.INVISIBLE);
			switchRefreshIconStatus(true);
		} else {
			APIRequestBus2 request;
			for(int i = 0; i < stopInfos.size(); i++) {
				StopInfo s = stopInfos.get(i);
				request = new APIRequestBus2(i, s.getStop_id(), this);
				
				request.execute(RequestMethod.API_GETSTATIONBYUID);
			}

			destroyRefreshTimer();
			setRefreshTimer();
			
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					progressBar.setVisibility(View.VISIBLE);
				}
			});
		}
	}
	private void setRefreshTimer() {
		if(stopInfos != null && stopInfos.size() > 0) {
			timerTask = new TimerTask() {
				@Override
				public void run() {
					refreshBusStopInfo();
				}
			};
			timer = new Timer();
			
			timer.schedule(timerTask, TIMER_INTERVAL, TIMER_INTERVAL);
		}
	}	
	private void destroyRefreshTimer() {
		if(timer != null)
			timer.cancel();
		if(timerTask != null)
			timerTask.cancel();
	}
	private void switchRefreshIconStatus(boolean enabled) {
		if(refreshingIcon != null) {
			if(enabled)
				refreshingIcon.setIcon(android.R.drawable.ic_popup_sync);
			else
				refreshingIcon.setIcon(android.R.drawable.ic_menu_recent_history);
			
			refreshingIcon.setEnabled(enabled);
		}
	}
	private void finishedAPIRequest() {
		sortBusStopInfo();
		switchRefreshIconStatus(true);
		progressBar.setVisibility(View.INVISIBLE);
	}
	private class PointListViewAdapter extends ArrayAdapter<StopInfo> {
		Context context;
		
		public PointListViewAdapter(Context context) {
			super(context, R.layout.listview_stop_info, stopInfos);
			this.context = context;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			StopInfo item = stopInfos.get(position);
			
			LayoutInflater inflater = ((Activity)context).getLayoutInflater();
			View row = (View)inflater.inflate(R.layout.listview_stop_info, null);
			
			TextView txtBusName = (TextView)row.findViewById(R.id.listview_stopinfo_text_busname);
			TextView txtRemainTime = (TextView)row.findViewById(R.id.listview_stopinfo_text_remaintime);
			TextView txtDetails = (TextView)row.findViewById(R.id.listview_stopinfo_text_details);
			TextView txtBusName2 = (TextView)row.findViewById(R.id.listview_stopinfo_text_busname2);
			
			txtBusName.setText(item.getBus_name());
			txtBusName.setTextColor(Color.parseColor(Actions.setBusTypeColor(item.getBus_type())));
			txtBusName2.setText(item.getStop_name() + "(" + item.getStop_id() + ")");
			
			if(item.getArriveInfo() != null) {
				GetStationByUidVo arriveInfo = item.getArriveInfo();
				int stationsToRemain = Integer.parseInt(arriveInfo.getStaOrd()) - Integer.parseInt(arriveInfo.getSectOrd1());
				
				txtRemainTime.setText("약 " + Actions.setTime(item.getArriveInfo().getTraTime1()));
				txtDetails.setText(stationsToRemain + "번째 전 정류소 (" + item.getArriveInfo().getStationNm1() + ") 출발");
			}
			
			return row;
		}
		
	}

	// Interfaces
	private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
		@Override
		public boolean onItemLongClick(AdapterView<?> arg0, View v, int position, long id) {
			PointList.this.position = position;
			DialogController.createDeleteStopInfoDialogAtLocal(PointList.this, v, stopInfos.get(position).getId(), PointList.this).show();
			return true;
		}
	};
	private Comparator<StopInfo> mComparator = new Comparator<StopInfo>() {
		@Override
		public int compare(StopInfo o1, StopInfo o2) {
			if(o1.getArriveInfo() == null)
				return 1;
			else if(o2.getArriveInfo() == null)
				return -1;
			
			int one = Integer.parseInt(o1.getArriveInfo().getTraTime1());
			int two = Integer.parseInt(o2.getArriveInfo().getTraTime1());
			
			if(one > two)
				return 1;
			else if(one == two)
				return 0;
			else
				return -1;
		}
	};
	
	// Delegates
	@Override
	public void onBusRequestCompleted(int requestCode, List<?> data) {
		StopInfo stopInfo = stopInfos.get(requestCode);
		List<GetStationByUidVo> stopList = (List<GetStationByUidVo>)data;
		
		for(GetStationByUidVo item : stopList) {
			if(item.getBusRouteId().equals(stopInfo.getBus_id())) {
				stopInfo.setArriveInfo(item);
				break;
			}
		}
		
		// Last row
		if(stopInfos.size() == requestCode + 1) {
			finishedAPIRequest();
		}
	}
	@Override
	public void onDeleteCompleted() {
		stopInfos.remove(position);
		position = -1;
		
		adapter.notifyDataSetChanged();
	}

	// ListActivity
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.pointlist);

		progressBar = (ProgressBar)findViewById(R.id.progressBar);
		
		// Preparing presentation data
		pointId = getIntent().getIntExtra("pointId", -1);
		point = LocalDaoFactory.getPoint(pointId);
		stopInfos = LocalDaoFactory.getStopinfosByPointID(pointId);
		
		if (pointId > 0) {
			adapter = new PointListViewAdapter(this);
			setListAdapter(adapter);
			
			this.getListView().setLongClickable(true);
			this.getListView().setOnItemLongClickListener(mItemLongClickListener);
		}
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch(requestCode) {
			case SEARCH_BUS_ACTIVITY:
				if(resultCode == RESULT_OK) {
					Bundle bundle = data.getExtras();
					
					StopInfo s = new StopInfo(0, 
							bundle.getString("stopCode"), 
							bundle.getString("stopName"), 
							bundle.getString("busCode"),
							bundle.getString("busName"), 
							bundle.getString("busType"),
							pointId);
					
					s.setId(LocalDaoFactory.insertStopinfo(s.getStop_id(), s.getStop_name(), s.getBus_id(), s.getBus_name(), s.getBus_type(), pointId));
					stopInfos.add(s);
					
					APIRequestBus2 request = new APIRequestBus2(stopInfos.size() - 1, s.getStop_id(), this);
					request.execute(RequestMethod.API_GETSTATIONBYUID);
					
					Toast.makeText(this, R.string.add_completed, Toast.LENGTH_SHORT).show();
					
					refreshBusStopInfo();
				}
				break;
			default:
				break;
		}
		
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		setRefreshTimer();
		refreshBusStopInfo();
	}

	@Override
	protected void onPause() {
		super.onPause();
		destroyRefreshTimer();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.pointlist, menu);
		actionBar = getActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);
		actionBar.setTitle(point.getName());
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		
		switch(item.getItemId()) {
			case android.R.id.home:
				intent = new Intent(this, RouteList.class);
	            startActivity(intent);
	            finish();
				break;
//			case R.id.action_add_points:
//				DialogController.createStationDialogAtLocal(PointList.this, pointId).show();
//				break;
			case R.id.action_refresh_points:
				refreshingIcon = item;
				switchRefreshIconStatus(false);
				refreshBusStopInfo();
				break;
			case R.id.action_add_points_use_activity:
				intent = new Intent(this, AddStopTabbed.class);
				startActivityForResult(intent, SEARCH_BUS_ACTIVITY);
				break;
			default:
				return false;
		}
		
		return true;
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		
		sortBusStopInfo();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Intent intentRouteList = new Intent(PointList.this, RouteList.class);
			startActivity(intentRouteList);
			finish();
		}
		return false;
	}
}
